/*
 * @Author: your name
 * @Date: 2021-09-15 09:34:48
 * @LastEditTime: 2021-09-16 13:45:08
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \media_system\routes\index.js
 */
const { Sequelize, DataTypes } = require("sequelize");
const moment = require('moment');
const { User, DietRecord, DietRecordDetail, Food } = require('../database/index')
const Router = require('@koa/router')
const { formatResponse,filterColumn } = require("../utils/common");
const router = new Router()
// 配置get路由
// router.get('/createFood', async function (ctx, next) {
//   const currentUser = await User.findOne({ where: { username: 'zs' } })
//   const currentLivingRoom = await LivingRoom.create({
//     title: '直播间1',
//     type: 1,
//   })
//   await currentUser.addLivingRooms([currentLivingRoom])
//   ctx.body = (await currentUser.getLivingRooms())[0].title
// })

//swagger食物模型暂未使用
/**
*  @swagger
*   components:
*     schemas:
*       foodModel:
*         type: object
*         properties:
*           foodName:          
*             type: string
*             description: 食物名称
*           protein:          
*            type: number
*            description: 蛋白质
*           fat:          
*            type: number
*            description: 脂肪
*           carbohydrate:          
*            type: number
*            description: 碳水
*           caloric:          
*             type: number
*             description: 热量
*           foodAvator:          
*             type: string
*             format: base64 # can use base64
*             description: 食物照片
*           foodDesc:       
*             type: string
*             description: 食物描述
*           foodWeight:
*             type: number
*             description: 食物重量
*/


/**
 * @swagger
 *  /dietRecord/add: #接口访问路径(拼接上之前swagger.js中的host)
 *    post: #请求方式
 *     summary: 添加当前用户饮食记录  #接口信息
 *     description: 添加当前用户饮食记录（dietRecordName饮食名称 category就餐类别（0 早餐，1午餐，2晚餐  3加餐）form就餐形式（0在家 1外出）） #接口描述
 *     tags: [饮食记录] #接口分组
 *     produces:
 *       - application/json
 *     consumes:
 *       - application/json
 *     requestBody:
 *         content:
 *            application/json:
 *               schema:
 *                  type: object
 *                  required:
 *                  - dietRecordName
 *                  - form
 *                  - category
 *                  - foods
 *                  properties:
 *                    userId:
 *                      type: string
 *                      description: 用户ID
 *                    dietRecordName:
 *                      type: string
 *                      description: 饮食名称
 *                    category:
 *                      type: integer
 *                      enum: [ "0", "1", "2", "3"]
 *                      description: 就餐类别（0 早餐，1午餐，2晚餐  3加餐）
 *                    form:
 *                      type: integer
 *                      enum: [ "0", "1"]
 *                      description: 就餐形式（0在家 1外出）
 *                    foods:
 *                      description: 食物数组
 *                      type: array
 *                      example: [
 *                                  {
 *                                    "foodId": "食物id",
 *                                    "foodWeight": 20,
 *                                  }
 *                               ]
 *                      items:     #$ref: '#/components/schemas/foodModel'
 *                        type: object
 *                        properties:
 *                          foodId:
 *                            type: string
 *                            description: 食物ID
 *                          foodWeight:
 *                            type: number
 *                            description: 食物重量
 * 
 *                          
 *     responses: #返回结果
 *       200:
 *         description: 成功
 */
router.post("/add", async function (ctx, next) {
  let dietRecord = ctx.request.body;
  // console.log("dietRecord:", dietRecord.foods[0]);
  const cDietRecord = await DietRecord.create({
    dietRecordName: dietRecord.dietRecordName,
    category: dietRecord.category,
    form: dietRecord.form
  });
  const cuser = User.build({
    userId: dietRecord.userId
  })
  await cDietRecord.setUser(cuser)
  dietRecord.foods.forEach(async f => {
    const cf = Food.build({
      foodId: f.foodId
    })
    await cDietRecord.addFood(cf, { through: { foodWeight: f.foodWeight } })
  })

  /** 插入饮食记录的同时插入关联食物
  // dietRecord.foods.forEach(async f => {
  //   await Food.create({
  //     foodName: f.foodName,
  //     protein: f.protein,
  //     fat: f.fat,
  //     carbohydrate: f.carbohydrate,
  //     caloric: f.caloric,
  //     foodAvator: f.foodAvator,
  //     foodDesc: f.foodDesc
  //   }).then((cf) => {
  //     cDietRecord.addFood(cf, { through: { foodWeight: f.foodWeight } })
  //   })
  // });
*/

  if (cDietRecord) {
    ctx.body = formatResponse("200", { ...cDietRecord.get({ plain: true }) }, "success");
  } else {
    ctx.body = formatResponse("500", "", "fail");
  }
});

/**
 * @swagger
 *  /dietRecord/update: #接口访问路径(拼接上之前swagger.js中的host)
 *    post: #请求方式
 *     summary: 更新当前用户饮食记录  #接口信息
 *     description: 更新当前用户饮食记录（dietRecordName饮食名称 category就餐类别（0 早餐，1午餐，2晚餐  3宵夜）form就餐形式（0在家 1外出）） #接口描述
 *     tags: [饮食记录] #接口分组
 *     produces:
 *       - application/json
 *     consumes:
 *       - application/json
 *     requestBody:
 *         content:
 *            application/json:
 *               schema:
 *                  type: object
 *                  required:
 *                  - dietRecordId
 *                  - dietRecordName
 *                  - foods
 *                  properties:
 *                    dietRecordId:
 *                      type: string
 *                      description: 饮食记录ID
 *                    dietRecordName:
 *                      type: string
 *                      description: 饮食名称
 *                    category:
 *                      type: integer
 *                      enum: [ "0", "1", "2", "3"]
 *                      description: 就餐类别（0 早餐，1午餐，2晚餐  3宵夜）
 *                    form:
 *                      type: integer
 *                      enum: [ "0", "1"]
 *                      description: 就餐形式（0在家 1外出）
 *                    foods:
 *                      description: 食物数组
 *                      type: array
 *                      example: [
 *                                  {
 *                                    "foodId": "食物id",
 *                                    "foodWeight": 20,
 *                                  }
 *                               ]
 *                      items:     #$ref: '#/components/schemas/foodModel'
 *                        type: object
 *                        properties:
 *                          foodId:
 *                            type: string
 *                            description: 食物ID
 *                          foodWeight:
 *                            type: number
 *                            description: 食物重量
 * 
 *                          
 *     responses: #返回结果
 *       200:
 *         description: 成功
 */
router.post("/update", async function (ctx, next) {
  let dietRecord = ctx.request.body;
  dietRecord = filterColumn(dietRecord)
  // console.log("dietRecord:", dietRecord.foods[0]);
  let cDietRecord = await DietRecord.findOne({
    where: {
      dietRecordId: dietRecord.dietRecordId,
    },
  });
  if(dietRecord.hasOwnProperty("foods")){
    let nfoods = []
    dietRecord.foods.forEach(async f => {
      const cf = Food.build({
        foodId: f.foodId
      })
      cf.dietRecordDetail = {//此处不能写DietRecordDetail，要写dietRecordDetail，太坑
        foodWeight: f.foodWeight
      }
      nfoods.push(cf)
    })
    await cDietRecord.setFoods(nfoods)
  }
  cDietRecord = await cDietRecord.update({
    ...dietRecord
  })
  if (cDietRecord) {
    ctx.body = formatResponse("200", { ...cDietRecord.get({ plain: true }) }, "success");
  } else {
    ctx.body = formatResponse("500", "", "fail");
  }
});

/**
 * @swagger
 * /dietRecord/getDietRecordByNow:
 *   get:
 *     security:
 *       - bearerAuth: []
 *     summary: 查询当前用户当天的饮食信息
 *     description: 查询当前用户当天的饮食信息
 *     tags: [饮食记录]
 *     parameters:
 *       - name: userId
 *         in: query #参数存放位置。query是存放到请求头里边
 *         required: true
 *         description: 用户id
 *         type: string
 *     responses:
 *       200:
 *         description: 成功
 */
router.get("/getDietRecordByNow", async function (ctx, next) {
  const Op = Sequelize.Op;
  const TODAY_START = moment().format('YYYY-MM-DD 00:00:00');
  const NOW = moment().format('YYYY-MM-DD 23:59:00');
  const { userId } = ctx.request.query;
  let dietRecords = await DietRecord.findAll({
    where: {
      userId,
      createdAt: {
        [Op.between]: [
          TODAY_START,
          NOW,
        ]
      },
    },
    include: {
      model: Food,
      as: 'foods' //定义belongsToMany的时候要加别名，这里关联的时候要加别名，不然输出的属性名是food而不是foods
    }
  });
  // console.log(dietRecords);//findAll返回的数组对象，不需要使用get({ plain: true }
  if (dietRecords) {
    ctx.body = formatResponse("200", dietRecords, "success");
  } else {
    ctx.body = formatResponse("500", "", "fail");
  }
});

/**
 * @swagger
 * /dietRecord/getDietRecordCaculateInfoByNow:
 *   get:
 *     security:
 *       - bearerAuth: []
 *     summary: 查询当前用户当天的饮食统计信息（总碳水，总脂肪，总蛋白质，总热量）
 *     description: 查询当前用户当天的饮食统计信息（总碳水，总脂肪，总蛋白质，总热量）
 *     tags: [饮食记录]
 *     parameters:
 *       - name: userId
 *         in: query #参数存放位置。query是存放到请求头里边
 *         required: true
 *         description: 用户id
 *         type: string
 *     responses:
 *       200:
 *         description: 成功
 */
router.get("/getDietRecordCaculateInfoByNow", async function (ctx, next) {
  const Op = Sequelize.Op;
  const TODAY_START = moment().format('YYYY-MM-DD 00:00:00');
  const NOW = moment().format('YYYY-MM-DD 23:59:00');
  const { userId } = ctx.request.query;
  let dietRecords = await DietRecord.findAll({
    where: {
      userId,
      createdAt: {
        [Op.between]: [
          TODAY_START,
          NOW,
        ]
      },
    },
    include: {
      model: Food,
      as: 'foods' //定义belongsToMany的时候要加别名，这里关联的时候要加别名，不然输出的属性名是food而不是foods
    }
  });
  // console.log(dietRecords);//findAll返回的数组对象，不需要使用get({ plain: true }
  if (dietRecords) {
    let breakfast = {
      //早餐
      totalProtein: 0,
      totalFat: 0,
      totalCarbohydrate: 0,
      totalCaloric: 0
    }
    let lunch = {
      //午餐
      totalProtein: 0,
      totalFat: 0,
      totalCarbohydrate: 0,
      totalCaloric: 0
    }
    let dinner = {
      //晚餐
      totalProtein: 0,
      totalFat: 0,
      totalCarbohydrate: 0,
      totalCaloric: 0
    }
    let snack = {
      //加餐
      totalProtein: 0,
      totalFat: 0,
      totalCarbohydrate: 0,
      totalCaloric: 0
    }
  
    dietRecords.forEach((d) => {
      if (d.category == 0) {
        d.foods.forEach((f) => {
          breakfast.totalProtein += f.protein * (f.dietRecordDetail.foodWeight / 100)
          breakfast.totalFat += f.fat * (f.dietRecordDetail.foodWeight / 100)
          breakfast.totalCarbohydrate += f.carbohydrate * (f.dietRecordDetail.foodWeight / 100)
          breakfast.totalCaloric += f.caloric * (f.dietRecordDetail.foodWeight / 100)
        })
      } else if (d.category == 1) {
        d.foods.forEach((f) => {
          lunch.totalProtein += f.protein * (f.dietRecordDetail.foodWeight / 100)
          lunch.totalFat += f.fat * (f.dietRecordDetail.foodWeight / 100)
          lunch.totalCarbohydrate += f.carbohydrate * (f.dietRecordDetail.foodWeight / 100)
          lunch.totalCaloric += f.caloric * (f.dietRecordDetail.foodWeight / 100)
        })
      } else if (d.category == 2) {
        d.foods.forEach((f) => {
          dinner.totalProtein += f.protein * (f.dietRecordDetail.foodWeight / 100)
          dinner.totalFat += f.fat * (f.dietRecordDetail.foodWeight / 100)
          dinner.totalCarbohydrate += f.carbohydrate * (f.dietRecordDetail.foodWeight / 100)
          dinner.totalCaloric += f.caloric * (f.dietRecordDetail.foodWeight / 100)
        })
      } else {
        d.foods.forEach((f) => {
          snack.totalProtein += f.protein * (f.dietRecordDetail.foodWeight / 100)
          snack.totalFat += f.fat * (f.dietRecordDetail.foodWeight / 100)
          snack.totalCarbohydrate += f.carbohydrate * (f.dietRecordDetail.foodWeight / 100)
          snack.totalCaloric += f.caloric * (f.dietRecordDetail.foodWeight / 100)
        })
      }
    })
    const totalCaculateInfo = {
      breakfast,
      lunch,
      dinner,
      snack
    }
    ctx.body = formatResponse("200", totalCaculateInfo, "success");
  }else{
    ctx.body = formatResponse("500", "", "fail");
  }
});

/**
 * @swagger
 * /dietRecord/getDietRecordByDates:
 *   get:
 *     security:
 *       - bearerAuth: []
 *     summary: 查询当前用户指定日期的饮食信息
 *     description: 查询当前用户指定日期的饮食信息
 *     tags: [饮食记录]
 *     parameters:
 *       - name: userId
 *         in: query #参数存放位置。query是存放到请求头里边
 *         required: true
 *         description: 用户id
 *         type: string
 *       - name: startDate
 *         in: query #参数存放位置。query是存放到请求头里边
 *         required: true
 *         description: 起始日期,例如2017-07-21
 *         type: string
 *       - name: endDate
 *         in: query #参数存放位置。query是存放到请求头里边
 *         required: true
 *         description: 结束日期,例如2017-07-21
 *         type: string
 *     responses:
 *       200:
 *         description: 成功
 */
router.get("/getDietRecordByDates", async function (ctx, next) {
  const { userId, startDate, endDate } = ctx.request.query;
  const Op = Sequelize.Op;
  const DATE_START = moment(startDate).format('YYYY-MM-DD 00:00:00');
  const DATE_END = moment(endDate).format('YYYY-MM-DD 23:59:00');
  let dietRecords = await DietRecord.findAll({
    where: {
      userId,
      createdAt: {
        [Op.between]: [
          DATE_START,
          DATE_END,
        ]
      },
    },
    include: {
      model: Food,
      as: 'foods' //定义belongsToMany的时候要加别名，这里关联的时候要加别名，不然输出的属性名是food而不是foods
    }
  });
  // console.log(dietRecords);//findAll返回的数组对象，不需要使用get({ plain: true }
  if (dietRecords) {
    ctx.body = formatResponse("200", dietRecords, "success");
  } else {
    ctx.body = formatResponse("500", "", "fail");
  }
});
/**
 * @swagger
 * /dietRecord/deleteDietRecord:
 *   get:
 *     security:
 *       - bearerAuth: []
 *     summary: 根据饮食ID删除饮食记录
 *     description: 根据饮食ID删除饮食记录
 *     tags: [饮食记录]
 *     parameters:
 *       - name: dietRecordIds
 *         in: query #参数存放位置。query是存放到请求头里边
 *         required: true
 *         description: 饮食ID
 *         schema:
 *          type: array
 *          items:
 *            type: string
 *     responses:
 *       200:
 *         description: 成功
 */
router.get("/deleteDietRecord", async function (ctx, next) {
  const { dietRecordIds } = ctx.request.query;
  const count = await DietRecord.destroy({
    where: {
      dietRecordId: dietRecordIds
    }
  });
  if (count > 0) {
    ctx.body = formatResponse("200", "", "success");
  } else {
    ctx.body = formatResponse("500", "", "fail");
  }
});
/**
 * @swagger
 * /dietRecord/getDietRecordsByPageAndCondition:
 *   get:
 *     security:
 *       - bearerAuth: []
 *     summary: 条件分页查询饮食记录
 *     description: 条件分页查询饮食记录
 *     tags: [饮食记录]
 *     parameters:
 *       - name: userId
 *         in: query #参数存放位置。query是存放到请求头里边
 *         description: 用户ID
 *         type: string
 *       - name: username
 *         in: query #参数存放位置。query是存放到请求头里边
 *         description: 用户名
 *         type: string
 *       - name: dietRecordName
 *         in: query #参数存放位置。query是存放到请求头里边
 *         description: 饮食名称
 *         type: string
 *       - name: category
 *         in: query #参数存放位置。query是存放到请求头里边
 *         description: 就餐类别（0 早餐，1午餐，2晚餐  3宵夜）
 *         type: integer
 *       - name: form
 *         in: query #参数存放位置。query是存放到请求头里边
 *         description: 就餐形式（0在家 1外出）
 *         type: integer
 *       - name: currentPage
 *         in: query #参数存放位置。query是存放到请求头里边
 *         required: true
 *         description: 当前第几页
 *         type: string
 *       - name: pageSize
 *         in: query #参数存放位置。query是存放到请求头里边
 *         required: true
 *         description: 一页几条记录
 *         type: string
 *     responses:
 *       200:
 *         description: 成功
 */
router.get("/getDietRecordsByPageAndCondition", async function (ctx, next) {
  const Op = Sequelize.Op;
  const { currentPage, pageSize, userId,username, dietRecordName, category, form } = ctx.request.query;
  offset = (currentPage - 1) * pageSize || 0;
  //条件1：饮食名称
  //条件2：就餐类别（0 早餐，1午餐，2晚餐  3宵夜）
  //条件3：就餐形式（0在家 1外出）
  const condition1 = dietRecordName ? { dietRecordName: { [Op.like]: `%${dietRecordName}%` } } : null;
  const condition2 = category ? { category } : null;
  const condition3 = form ? { form } : null;
  // let result = await DietRecord.findAndCountAll({
  //   where: Object.assign({}, condition1, condition2, condition3),
  //   order: [['createdAt', 'DESC']],
  //   offset,
  //   limit: parseInt(pageSize),
  //   include:{
  //     model: User,
  //     where:{userId}, //这种会inner join
  //     attributes: ['username','specialCondition'],
  //   }
  // });

  //条件4这种是left outer join
  const condition4 = userId ? { userId } : null;
  const condition5 = username ? { username } : null;
  let result = await DietRecord.findAndCountAll({
    where: Object.assign({}, condition1, condition2, condition3, condition4),
    order: [['createdAt', 'DESC']],
    offset,
    limit: parseInt(pageSize),
    include: {
      model: User,
      where:Object.assign({}, condition5),
      attributes: ['username','realname', 'weight', 'bmi', 'specialCondition'],
    }
  });
  if (result) {
    ctx.body = formatResponse("200", result, "success");
  } else {
    ctx.body = formatResponse("500", "", "fail");
  }
});

/**
 * @swagger
 * /dietRecord/getDietRecordById:
 *   get:
 *     security:
 *       - bearerAuth: []
 *     summary: 根据饮食记录ID查询饮食记录详情
 *     description: 根据饮食记录ID查询饮食记录详情
 *     tags: [饮食记录]
 *     parameters:
 *       - name: dietRecordId
 *         in: query #参数存放位置。query是存放到请求头里边
 *         description: 饮食记录ID
 *         type: string
 *     responses:
 *       200:
 *         description: 成功
 */
router.get("/getDietRecordById", async function (ctx, next) {
  const { dietRecordId } = ctx.request.query;
  let cDietRecord = await DietRecord.findOne({
    where: { dietRecordId },
    include: {
      model: Food,
      as: 'foods' //定义belongsToMany的时候要加别名，这里关联的时候要加别名，不然输出的属性名是food而不是foods
    }
  });
  if (cDietRecord) {
    ctx.body = formatResponse("200", cDietRecord, "success");
  } else {
    ctx.body = formatResponse("500", "", "fail");
  }
});

/**
 * @swagger
 * /dietRecord/getAllDietRecord:
 *   get:
 *     security:
 *       - bearerAuth: []
 *     summary: 查询所有饮食记录
 *     description: 查询所有饮食记录
 *     tags: [饮食记录]
 *     responses:
 *       200:
 *         description: 成功
 */
router.get("/getAllDietRecord", async function (ctx, next) {
  let dietRecords = await DietRecord.findAll();
  if (dietRecords) {
    ctx.body = formatResponse("200", dietRecords, "success");
  } else {
    ctx.body = formatResponse("500", "", "fail");
  }
});

module.exports = router